﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using hes.models;
using hes.data_access;
using System.Diagnostics;

namespace hes.controllers
{

    // EndTermController handles ending a term
    class EndTermController
    {
        // Function: Ends the term for the current student
        // Preconditions: a current student is selected
        // Postcondtions: the database TermItem for the student is marked as done
        public void EndTerm(DateTime end_date) //, int stu_id, int term_id)
        {
            Student currStudent = SystemController.Instance.CurrentStudent;
            StudentTermDAO termdao = new StudentTermDAO(Connector.Instance.Connection);

            try
            {
                int termid = termdao.GetCurrentStudentTerm(currStudent.StudentID);

                SaveFinalCourseGrades(currStudent, termid);

                termdao.EndTerm(currStudent.StudentID, termid, end_date);

                Debug.WriteLine(DateTime.Now + ": Student " + currStudent.FirstName + " " + currStudent.LastName + " has succesfully Ended the Term - EndTermController");

                StudentTermDAO stdao = new StudentTermDAO(Connector.Instance.Connection);

                stdao.NewStudentTerm(currStudent.StudentID, termid + 1, 40);
            } catch (Exception e) {
                e.ToString();
                Debug.WriteLine(DateTime.Now + ": Student " + currStudent.FirstName + " " + currStudent.LastName + " has unsuccesfully Ended the Term - EndTermController");
                Debug.WriteLine("EndTermController has thrown a database exception in the EndTerm method");
            }
        }

        /// <summary>
        /// NumDays() use to pass back to main form to see if instruct_days == the value needed in the db
        /// </summary>
        /// <returns> Returns the number of days required</returns>
        public int NumDays()
        {
            StudentDAO stdao = new StudentDAO(Connector.Instance.Connection);            
            StudentTermDAO termdao = new StudentTermDAO(Connector.Instance.Connection);
            int id = SystemController.Instance.CurrentStudent.StudentID;
            return termdao.GetDaysNeeded(id, termdao.GetCurrentStudentTerm(id));
        }

        /// <summary>
        /// SaveFinalCourseGrades(Student, int) updates the TERM_ITEM database with the calculated final grades
        /// </summary>
        /// <param name="stud">This is the student that the function will look for in the database</param>
        /// <param name="currentTerm">This is the term of the student that the function will use to access the db</param>
        private void SaveFinalCourseGrades(Student stud, int currentTerm)
        {
            // get all the term items
            ArrayList term_items = new ArrayList();
            TermItemDAO t_itemDAO = new TermItemDAO(Connector.Instance.Connection);
            term_items = t_itemDAO.FindCurrentStudentTermItems(stud.StudentID, currentTerm);

            AssignmentCategoryDAO ascDAO = new AssignmentCategoryDAO(Connector.Instance.Connection);
            AssignmentDAO asmtDAO = new AssignmentDAO(Connector.Instance.Connection);

            

            foreach (TermItem t_item in term_items)
            {
                ArrayList assignment_categories = ascDAO.Find(t_item.ID);

                ArrayList cat_contribs = new ArrayList();

                foreach (AssignmentCategory cat in assignment_categories)
                {
                    ArrayList asmts = asmtDAO.FindCatAssignments(cat.CategoryID);


                    int totalPtsEarned = 0;
                    int totalPtsPossible = 0;
                    foreach (Assignment asmt in asmts)
                    {
                        if (asmt.PointsPossible != 0)
                        {
                            totalPtsEarned += asmt.PointsEarned;
                            totalPtsPossible += asmt.PointsPossible;
                        }
                    }

                    double cat_percentage = Convert.ToDouble(Convert.ToDouble(totalPtsEarned) / Convert.ToDouble(totalPtsPossible));

                    double contribution = cat_percentage * Convert.ToDouble(cat.CategoryPercent) * 0.01 ;

                    cat_contribs.Add(contribution);

                }

                double final = 0;
                foreach (double contrib in cat_contribs)
                {
                    final += contrib;
                }

                int finalgrade = Convert.ToInt32((final) * 100);

                t_itemDAO.UpdateFinalGrade(t_item.ID, finalgrade);

                Debug.WriteLine(DateTime.Now + ": Term Item Final Grade " + t_item.ID + "Updated - EndTermController");



            }

        }

    }
}
